package com.smartStatus.admin.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.smartStatus.admin.mapper.SysMenuMapper;
import com.smartStatus.admin.mapper.SysUserMapper;
import com.smartStatus.admin.service.*;
import com.smartStatus.admin.utils.JoinUtil;
import com.smartStatus.api.dto.SysUserImportDTO;
import com.smartStatus.api.entity.*;
import com.smartStatus.api.vo.SysGradeVO;
import com.smartStatus.api.vo.SysUserVO;
import com.smartStatus.core.constant.StatusUser;
import com.smartStatus.core.util.R;
import com.smartStatus.core.util.SecretUtils;
import com.smartStatus.security.utils.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.util.StringUtil;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户表 服务实现类
 * </p>
 *
 * @author lby
 * @since 2021-01-11
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    private final CommonParametersService commonParametersService;
    private final GradeClassService gradeClassService;
    private final UserClassService userClassService;
    private final TenantGradeService tenantGradeService;
    private final SysRoleService sysRoleService;
    private final SysMenuMapper sysMenuMapper;
    private final SysUserTenantService sysUserTenantService;
    private final SysTenantService sysTenantService;
    private final SysMenuPermissionService sysMenuPermissionService;

    @Override
    public Boolean saveUserRole(Integer userId, Integer roleId) {
        return baseMapper.saveUserRole(userId, roleId);
    }

    @Override
    public Integer countUsers(SysUser sysUser) {
        return baseMapper.countUsers(sysUser);
    }

    @Override
    public Map<String, Object> importUserLists(List<SysUserImportDTO> userImportDTO, List<Integer> roleIdList) throws Exception {
        /*错误数据*/
        List<SysUser> errorList = new ArrayList<>();
        /*正确数据*/
        List<SysUser> successList = new ArrayList<>();
        SysUserVO userVO = new SysUserVO();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        for (SysUserImportDTO dtoData : userImportDTO) {
            String encrypt = SecretUtils.encrypt(dtoData.getPassword());
            userVO.setPassword(encrypt);
            userVO.setRoleIdList(roleIdList);
            userVO.setUserName(dtoData.getUserName());
            userVO.setName(dtoData.getName());
            userVO.setEmail(dtoData.getEmail());
            userVO.setPhone(dtoData.getPhone());
            userVO.setFamousFamily(dtoData.getFamousFamily());
            try {
                userVO.setBirthday(dtoData.getBirthday());
            } catch (Exception e) {
                log.error("导入错误:{}", e.getMessage());
                return null;
            }
            userVO.setJobNumber(dtoData.getJobNumber());
            userVO.setIdCard(dtoData.getIdCard());
            userVO.setState(false);
            // 判断用户选择的学校
            if (StringUtils.isNotBlank(dtoData.getTenantName())) {
                QueryWrapper<SysTenant> query = Wrappers.query();
                query.eq("name", dtoData.getTenantName());
                SysTenant one = sysTenantService.getOne(query);
                if (one == null) {
                    errorList.add(userVO);
                } else {
                    userVO.setTenantId(one.getId());
                }
            }
            // 教师的租户就是当前用户的租户
            else {
                userVO.setTenantId(SecurityUtils.getUser().getTenantId());
            }
            if ("男".equals(dtoData.getSex())) {
                userVO.setSex(0);
            } else {
                userVO.setSex(1);
            }
            QueryWrapper<SysUser> query = Wrappers.query();
            query.eq("name", userVO.getName());
            if (userVO.selectCount(query) > 0) {
                errorList.add(userVO);
            } else {
                if (this.saveUser(userVO)) {
                    successList.add(userVO);
                } else {
                    errorList.add(userVO);
                }
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("errorList", errorList);
        map.put("successList", successList);
        return map;
    }

    @Override
    public List<SysGradeVO> getUserClasses(Integer tenantId, SysUserVO sysUserVO) {
        if (tenantId != null) {
            QueryWrapper<TenantGrade> query1 = Wrappers.query();
            query1.eq("tenant_id", tenantId);
            List<TenantGrade> tenantGrades = tenantGradeService.list(query1);
            List<SysGradeVO> gradeVOList = new ArrayList<>();
            for (TenantGrade t : tenantGrades) {
                QueryWrapper<GradeClass> query2 = Wrappers.query();
                // 班级list
                List<SysClasses> classesList = new ArrayList<>();
                query2.eq("grade_id", t.getGradeId());
                List<GradeClass> list = gradeClassService.list(query2);
                list.forEach(gradeClass -> {
                    SysClasses sysClasses = new SysClasses();
                    sysClasses.setId(gradeClass.getClassId());
                    SysClasses sysClasses1 = sysClasses.selectById();
                    classesList.add(sysClasses1);
                });
                SysGradeVO gradeVO = new SysGradeVO();
                gradeVO.setId(t.getGradeId());
                SysGrade sysGrade = gradeVO.selectById();
                SysGradeVO entity = JoinUtil.entity(sysGrade, SysGradeVO.class);
                entity.setClassesList(classesList);
                QueryWrapper<UserClass> query3 = Wrappers.query();
                query3.eq("user_id", sysUserVO.getId());
                UserClass one = userClassService.getOne(query3);
                List<Integer> list1 = new ArrayList<>();
                if (one != null) {
                    list1.add(one.getClassId());
                    entity.setSelectedChecks(list1);
                }
                gradeVOList.add(entity);
            }
            return gradeVOList;
        } else {
            return null;
        }
    }


    @Override
    public List<SysUser> getStudents(@Param("roleId") Integer roleId) {
        return baseMapper.getStudents(roleId);
    }


    @Override
    public Map<String, Object> getUserRoles(SysUser sysUser) {
        Map<String, Object> map = new HashMap<>();
        List<Integer> roleNames = new ArrayList<>();
        List<String> permissions = new ArrayList<>();
        // 获取用户角色
        List<SysRole> userRoleLists = sysRoleService.getUserRoleLists(sysUser);
        // 获取角色对应的路由
        userRoleLists.forEach(sysRole -> {
            roleNames.add(sysRole.getId());
            List<Integer> menuIds = sysRoleService.getMenuIds(sysRole);
            if (menuIds != null && menuIds.size() > 0) {
                QueryWrapper<SysMenuPermission> sysMenuPermissionQueryWrapper = Wrappers.query();
                sysMenuPermissionQueryWrapper.in("menu_id", menuIds);
                sysMenuPermissionQueryWrapper.eq("checked","1");
                List<SysMenuPermission> sysMenuPermissions = sysMenuPermissionService.list(sysMenuPermissionQueryWrapper);
                if (sysMenuPermissions != null && sysMenuPermissions.size() > 0) {
                    List<String> permissionList = sysMenuPermissions.stream().map(SysMenuPermission::getPermission).collect(Collectors.toList());
                    permissions.addAll(permissionList);
                }
            }
        });
        String[] pre = new String[permissions.size()];
        permissions.toArray(pre);
        Integer[] role = new Integer[roleNames.size()];
        roleNames.toArray(role);
        map.put("role", role);
        map.put("pre", pre);
        return map;
    }


    @Override
    public Boolean saveUser(SysUserVO sysUserVO) throws Exception {
        /*用户名不可重复*/
        QueryWrapper<SysUser> query = Wrappers.query();
        query.eq("name", sysUserVO.getName());
        QueryWrapper<SysUser> query2 = Wrappers.query();
        query2.eq("id_card", sysUserVO.getIdCard());
        // 员工号不能重复
        QueryWrapper<SysUser> query1 = Wrappers.query();
        query1.eq("job_number", sysUserVO.getJobNumber());
        if (sysUserVO.selectCount(query) > 0 || sysUserVO.selectCount(query2) > 0 || sysUserVO.selectCount(query1) > 0) {
            return false;
        }
        // 设置为Bsypt加密
        String decrypt = SecretUtils.decrypt(sysUserVO.getPassword());
        String hashpw = BCrypt.hashpw(decrypt, BCrypt.gensalt());
        sysUserVO.setPassword(hashpw);
        this.save(sysUserVO);
        // 存储用户租户对应关系
        SysUserTenant sysUserTenant = new SysUserTenant();
        sysUserTenant.setTenantId(sysUserVO.getTenantId());
        sysUserTenant.setUserId(sysUserVO.getId());
        sysUserTenantService.save(sysUserTenant);
        SysUser user = sysUserVO.selectOne(query);
        if (sysUserVO.getRoleIdList().size() > 0) {
            sysUserVO.getRoleIdList().forEach(value -> {
                this.saveUserRole(user.getId(), value);
            });
        }
        // 如果用户没有选择角色，默认学生角色
        else {
            this.saveUserRole(user.getId(), 4);
        }
        return true;
    }

    @Override
    public R getUserInfo() {
        StatusUser user = SecurityUtils.getUser();
        SysUser one = this.getById(user.getId());
        SysUserVO entity = JoinUtil.entity(one, SysUserVO.class);
        List<SysRole> userRoleLists = sysRoleService.getUserRoleLists(one);
        entity.setRoleList(userRoleLists);
        Map<String, Object> userRoles = this.getUserRoles(one);
        entity.setPermissionList((String[]) userRoles.get("pre"));
        return R.ok(entity);
    }
}
